JSON-WEB-TOKEN-JWT

毫無反應,就是個 JWT (JSON Web Token)

什麼是 JWT?

  • 一種基於 JSON 格式,用於傳輸信任資訊的簽章 (signature) 與編碼 (encoding) 技術
    • 因此資料可以反解 (decoding) 回去
  • 常用於分散式環境下,取代 session 認證,可擴展的解決方案
    • 單點認證
      • JWT 描述使用者資訊,可達成無狀態 (stateless)
  • e.g. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Session 的問題?

session

  • Server 記憶體消耗
  • 擴展困難
    • 跨主機間的 session 共享?
  • CSRF
    CSRF

JWT 運作流程

JWT flow

https://cdn.auth0.com/content/jwt/jwt-diagram.png

  • Server-side 無需保存 users 資料 => 無記憶體消耗
  • JWT 本身包含所需的使用資料,可達成 stateless HTTP APIs => 方便擴展
  • JWT 的存放可以完全不透過 Cookies => 沒有 CSRF 的可能

JWT 原理

JWT elements

Header

  • 描述使用的簽章演算法,並透過 Base64URL 編碼
    • 對稱 / 非對稱加密皆可使用,通常使用 HMAC256

Payload

  • 描述使用者與提供者所需要的資訊,並透過 Base64URL 編碼
    • 避免儲存敏感資料
  • 另外有標準特別規範的聲明 (並未硬性要求)
    • iss: Issuer,JWT 的簽章者,可驗證是否原本的簽章者簽章
    • sub: Subject,此 JWT 底下服務的服務,需要局部或全域唯一 (unique)
    • aud: Audience,接收此 JWT 的使用者,一個可被 identify 的 StringOrURI
    • exp: JWT 過期時間,此數值必須大於簽章時間,單位為秒
    • nbf: 定義在此時間點以前,JWT 都是不可用的
    • iat: JWT 的簽章時間
    • jti: JWT 的唯一識別,可用於一次性 koken,避免重放攻擊 (replay attack)

Signature

  • HeaderPayload. 相連,然後根據指定的演算法,加上 secret key 簽章
    • 若是使用非對稱 RSA 加密,則透過 private key 簽章,然後透過 public key 驗證

HeaderPayloadSignature 分別以 . 相連的結果,即為我們產生的 token

注意

  • 通常會使用 Base64URL 編碼取代 Base64
    • Base64URL 會另外處理瀏覽器 URL 上的特殊符號
    • e.g. “+” => “-”, “/” => “_”
  • Base64URL 是可反解的,避免儲存敏感資料
  • Secret Key 只存在 Server,需妥善保管
  • JWT 的產生與驗證皆只在 Server-side 完成

驗證

  • 將 Client 傳輸過來的 token,取出 Header 與 Payload 的部份,根據 Header 描述的演算法,配合 secret key 重新運算簽章流程,比較是否與 Signature 相同,相同則表示未經偽造。
  • 另外將 Payload 解碼,取出聲明依序驗證(可包含規範與自定的聲明)
    • e.g. 驗證 exp 是否有大於當前時間,若否,則失效

使用

  • Client 每次請求時,皆會帶上 token 給 Server 驗證
  • 正規作法是透過 HTTP 的 Authorization header,以 Bearer ${token} 的形式帶上
    • e.g. Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
    • Bearer 只是描述要以 JWT 的方式驗證,沒有硬性規定,以 Client 與 Server 約定為主
  • 亦可透過 GET 的的 query string (較不建議) 或 set cookies (有 CSRF 風險) 的形式達成

JWT demo with koa2

JWT 的繆誤

  • 並非加密 (encryption) 機制,資料可被解碼,並且只是單純的驗證資訊是否被竄改
    • 因此沒有能力確保資料安全,避免存放敏感資料
    • 確保資料安全請用 SSL/TLS

其他

  • 根據使用的安全性需求,調整 token 的壽命,或者是使用一次性 token
  • jwt.io 有提供 Debugger 與建議的各語言實作套件清單

參考資料

Share